package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.xbongbong.admin.domain.entity.AppInstallEntity;
import com.xbongbong.admin.model.AppInstallModel;
import com.xbongbong.admin.model.FormInstallModel;
import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.admin.pojo.vo.MirrorRollBackVO;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.feign.WorkOrderClient;
import com.xbongbong.paas.help.menu.InitCrmMenuHelp;
import com.xbongbong.paas.help.menu.InitJxcMenuHelp;
import com.xbongbong.paas.help.menu.InitMarketManagementHelp;
import com.xbongbong.paas.help.menu.InitWorkOrderHelp;
import com.xbongbong.paas.manager.feign.MirrorFeignClent;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.MirrorService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.saas.enums.MirrorRollBackTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

/**
 * 镜像功能
 * @author xingxing.xiao
 */
@Service("mirrorService")
public class MirrorServiceImpl implements MirrorService {
    private static final Logger LOG = LoggerFactory.getLogger(MirrorServiceImpl.class);


    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private InitCrmMenuHelp initCrmMenuHelp;
    @Resource
    private InitJxcMenuHelp initJxcMenuHelp;
    @Resource
    private InitWorkOrderHelp initWorkOrderHelp;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private MirrorFeignClent mirrorFeignClent;
    @Resource
    private AppInstallModel appInstallModel;
    @Resource
    private FormInstallModel formInstallModel;
    @Resource
    private InitMarketManagementHelp initMarketManagementHelp;

    @Resource
    private WorkOrderClient workOrderClient;

    /**
     * 返回操作
     * @param mirrorRollBackDTO
     * @return
     * @throws XbbException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MirrorRollBackVO rollBackToInit(MirrorRollBackDTO mirrorRollBackDTO) throws XbbException {
        String hashKey = mirrorRollBackDTO.getTargetCorpid() + "_"+mirrorRollBackDTO.getAlias();
        MirrorRollBackVO mirrorRollBackVO = new MirrorRollBackVO();
        String corpid = mirrorRollBackDTO.getTargetCorpid();
        SystemAppMenuEnum systemAppMenuEnum = SystemAppMenuEnum.getSystemAppMenuEnum(mirrorRollBackDTO.getAlias());
        Long appInstallId = mirrorRollBackDTO.getAppInstallId();
        AppInstallEntity appInstallEntity = appInstallModel.getByKey(appInstallId, corpid);
        String formIds = appInstallEntity.getFormIds();
        List<Long> installFormList = JSONArray.parseArray(formIds, Long.class);
        try {
            //校验是否存在数据
            HashMap<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("appId", mirrorRollBackDTO.getAppId());
            param.put("corpid", corpid);
            param.put("idIn", installFormList);
            List<PaasFormEntity> paasFormModelEntitys = paasFormModel.findEntity(param);
            List<Long> systemFormList = new ArrayList<>();
            paasFormModelEntitys.forEach(item -> {
                if (Objects.equals(item.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                    systemFormList.add(item.getId());
                }
            });
            //我也不想在这里定义一个产品表单,但是下边更新表单解释要用,木得办法
            PaasFormEntity productFormEntity =  paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
            //回退应用(从表单开始,表单->表单解释->菜单->应用)
            switch (systemAppMenuEnum){
                case CRM:
                    initCrmMenuHelp.rollBackInit(mirrorRollBackDTO, systemFormList, productFormEntity);
                    break;
                case JXC:
                    newCheckData(mirrorRollBackDTO);
                    initJxcMenuHelp.rollBackInit(mirrorRollBackDTO, systemFormList, productFormEntity);
                    break;
                case WORK_ORDER:
                    newCheckData(mirrorRollBackDTO);
                    initWorkOrderHelp.rollBackInit(mirrorRollBackDTO, systemFormList, productFormEntity);
                    break;
                case MARKET_MANAGEMENT:
                    newCheckData(mirrorRollBackDTO);
                    initMarketManagementHelp.rollBackInit(mirrorRollBackDTO, systemFormList, productFormEntity);
                    break;
                case WORK_ORDER_V2_CENTER:
                    newCheckData(mirrorRollBackDTO);
                    mirrorRollBackDTO.setInstallFormList(systemFormList);
                    String responseStr = workOrderClient.rollbackInit(mirrorRollBackDTO,LocaleContextHolder.getLocale().toString());
                    XbbResponse response = JSONArray.parseObject(responseStr,XbbResponse.class);
                    if (response == null || !response.isSuccess()) {
                        LOG.error("回退工单v2初始化错误！");
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                    }
                    break;
                default:
                    break;
            }
            //更新应用回退到上一版本的值为MirrorRollBackTypeEnum.ROLL_BACK_TO_PREVIOUS,回退到初始化的值为MirrorRollBackTypeEnum.ROLL_BACK_TO_INIT.getFlag()
            appInstallEntity.setIsToPrevious(MirrorRollBackTypeEnum.ROLL_BACK_TO_PREVIOUS.getFlag());
            appInstallEntity.setIsToInit(MirrorRollBackTypeEnum.ROLL_BACK_TO_INIT.getFlag());
            appInstallModel.update(appInstallEntity);
            formInstallModel.deleteByAppInstallId(corpid,appInstallEntity.getId());
            // 删除tb_form_install表中关联表单
            // formInstallModel.deleteByAppIdAndCorpid(mirrorRollBackDTO.getCorpid(),mirrorRollBackDTO.getAppId());
            //添加一天一个应用一加公司只允许回退2次
            String value = paasRedisHelper.getValue(RedisPrefixConstant.MIRROR_ROLLBACK, hashKey);
            if (Objects.nonNull(value) && !Objects.equals(value,Integer.toString(0))){
                Integer integer = Integer.valueOf(value);
                integer--;
                paasRedisHelper.setValue(RedisPrefixConstant.MIRROR_ROLLBACK,hashKey,integer, RedisConstant.LONG_DURATION);
            }else {
                paasRedisHelper.setValue(RedisPrefixConstant.MIRROR_ROLLBACK,hashKey,2, RedisConstant.LONG_DURATION);
            }
            mirrorRollBackVO.setMirrorId(mirrorRollBackDTO.getMirrorId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("回退到初始化出错");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return mirrorRollBackVO;
    }

    @Override
    public Boolean newCheckData(MirrorRollBackDTO mirrorRollBackDTO) throws XbbException{
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        XbbResponse<MirrorRollBackVO> mirrorRollBackVOXbbResponse = mirrorFeignClent.checkData(mirrorRollBackDTO, lang);
        if (mirrorRollBackVOXbbResponse.isSuccess()) {
            return true;
        } else {
            throw new XbbException(mirrorRollBackVOXbbResponse.getCode(), mirrorRollBackVOXbbResponse.getMsg());
        }
    }

    @Override
    public MirrorRollBackVO rollBackToPrevious(MirrorRollBackDTO mirrorRollBackDTO) throws XbbException {
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        XbbResponse<MirrorRollBackVO> mirrorRollBackVOXbbResponse = mirrorFeignClent.rollBackToPrevious(mirrorRollBackDTO, lang);
        if (mirrorRollBackVOXbbResponse.isSuccess()) {
            return mirrorRollBackVOXbbResponse.getResult();
        } else {
            throw new XbbException(mirrorRollBackVOXbbResponse.getCode(), mirrorRollBackVOXbbResponse.getMsg());
        }
    }
}
